package com.google.code.mochaccino.framework.ui.demo.pages;
/*
 * Copyright 2012 Claude Houle claude.houle@gmail.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import com.google.code.mochaccino.framework.freemarker.TemplateManager;
import com.google.code.mochaccino.framework.rest.mime.MimeTypes;
import com.google.code.mochaccino.framework.ui.demo.SubjectUtil;
import com.google.code.mochaccino.framework.ui.freemarker.TemplateOutput;
import com.google.code.mochaccino.framework.ui.freemarker.TemplateUtil;
import com.google.code.mochaccino.framework.ui.i18n.ResourceBundleUtil;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.inject.Inject;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresGuest;
import org.apache.shiro.subject.Subject;


/**
 *
 */
@Path( Login.PATH )
public class Login {

	public static final String PATH      = "/login";
	public static final String PATH_AUTH = "/auth";
	public static final String PATH_I18N = "/i18n";

	/** Template Manager */
	private TemplateManager manager;

	/** The Login Service */
	private LoginService service = null;

	@Inject
	public Login( TemplateManager manager, LoginService service ) {
		this.manager = manager;
		this.service = service;
	}

	/** Authenticate */
	@Path( PATH_AUTH )
	@POST
	@Consumes( MediaType.APPLICATION_FORM_URLENCODED )
	@Produces( MediaType.TEXT_HTML )
	@RequiresGuest

	public Response login_auth( @FormParam( "username" ) String username, @FormParam( "password" ) String password, @FormParam( "lang" ) String language ) throws URISyntaxException {
		Subject subject = SecurityUtils.getSubject();
		Locale locale = SubjectUtil.setLocale( language );
		try {
			subject.login( new UsernamePasswordToken( username, password ) );
		} catch ( AuthenticationException e ) {
			return Response.status( Status.UNAUTHORIZED ).entity( ResourceBundleUtil.getResourceBundle( "web/pages/login/login", locale ).getString( "MsgLoginFailed" ) ).build();
		}

		if ( service.passwordChangeRequired( username ) ) {
			String uri = ChangePassword.PATH + "?lang=" + locale.getLanguage() + "&user=" + username + "&token=" + service.getChangePasswordToken( username );
			return Response.ok( uri ).build();
		}

		String uri = service.getSuccessLoginURL().toASCIIString();
		return Response.ok().entity( uri ).build();
	}

	/** Login CSS */
	@GET
	@Produces( MimeTypes.TYPE_CSS )

	public Response login_css() {
		return Response.ok().entity( new TemplateOutput( manager, "/web/pages/login/login.less.ftl" ) ).build();
	}

	/** Login HTML */
	@GET
	@Produces( MediaType.TEXT_HTML )

	public Response login_html( @QueryParam( "lang" ) String lang ) {

		if ( SecurityUtils.getSubject().isAuthenticated() ) {
			try {
				return Response.temporaryRedirect( new URI( Frame.PATH ) ).build();
			} catch ( URISyntaxException e ) {
				throw new WebApplicationException( e );
			}
		}

		return login_html( SubjectUtil.setLocale( lang ), false ).build();
	}

	@Path( PATH_I18N )
	@POST
	@Consumes( MediaType.APPLICATION_FORM_URLENCODED )
	@Produces( MediaType.TEXT_HTML )
	@RequiresGuest

	public Response login_i18n( @FormParam( "language" ) String lang ) throws URISyntaxException {
		SubjectUtil.setLocale( lang );
		return Response.ok().build();
	}

	public ResponseBuilder login_html( Locale loc, boolean refreshOnSuccess ) {
		Map<String,Object> parameters = new HashMap<String,Object>();
		parameters.put( "env", service.getEnvironment() );
		parameters.put( "langChoices", TemplateUtil.getLocaleListModel( service.getLanguages(), loc.toString() ) );
		parameters.put( "i18n", ResourceBundleUtil.getResourceBundleModel( "web/pages/login/login", loc ) );
		parameters.put( "redirectUrl", Frame.PATH );
		parameters.put( "urlForgotPwd", ForgotPassword.PATH );
		parameters.put( "urlI18n", PATH + PATH_I18N );
		parameters.put( "urlAuth", PATH + PATH_AUTH );
		parameters.put( "refreshOnSuccess", refreshOnSuccess );
		return Response.ok().entity( new TemplateOutput( manager, "/web/pages/login/login.html.ftl", parameters ) );
	}
}
